package com.xjx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjx.common.PageResult;
import com.xjx.enums.ErrorCode;
import com.xjx.exception.ServiceException;
import com.xjx.mapper.BookMapper;
import com.xjx.pojo.dto.BookCreateDTO;
import com.xjx.pojo.dto.BookPageQuery;
import com.xjx.pojo.dto.BookUpdateDTO;
import com.xjx.pojo.dto.StockAdjustDTO;
import com.xjx.pojo.entity.Book;
import com.xjx.pojo.vo.BookVO;
import com.xjx.service.BookService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {

    @Override
    public BookVO createBook(BookCreateDTO createDTO) {
        if (this.count(new LambdaQueryWrapper<Book>().eq(Book::getIsbn, createDTO.getIsbn())) > 0) {
            throw new ServiceException(ErrorCode.CONFLICT, "该ISBN已存在");
        }
        Book book = new Book();
        BeanUtils.copyProperties(createDTO, book);
        if (!this.save(book)) {
            throw new ServiceException(ErrorCode.DATABASE_ERROR, "新增图书失败");
        }
        return convertToVO(book);
    }

    @Override
    public BookVO updateBook(Long id, BookUpdateDTO updateDTO) {
        Book book = this.getById(id);
        if (book == null) {
            throw new ServiceException(ErrorCode.NOT_FOUND, "图书不存在");
        }
        BeanUtils.copyProperties(updateDTO, book);
        if (!this.updateById(book)) {
            throw new ServiceException(ErrorCode.DATABASE_ERROR, "更新失败，可能存在并发修改");
        }
        return convertToVO(book);
    }

    @Override
    public BookVO adjustStock(Long id, StockAdjustDTO adjustDTO) {
        Book book = this.getById(id);
        if (book == null) {
            throw new ServiceException(ErrorCode.NOT_FOUND, "图书不存在");
        }
        int newStock = book.getStock() + adjustDTO.getQuantity();
        if (newStock < 0) {
            throw new ServiceException(ErrorCode.INSUFFICIENT_STOCK);
        }
        book.setStock(newStock);
        this.updateById(book);
        return convertToVO(book);
    }

    @Override
    public BookVO getBookById(Long id) {
        Book book = this.getById(id);
        if (book == null) {
            throw new ServiceException(ErrorCode.NOT_FOUND, "图书不存在");
        }
        return convertToVO(book);
    }

    @Override
    public Map<String, Boolean> checkIsbnExists(String isbn) {
        long count = this.count(new LambdaQueryWrapper<Book>().eq(Book::getIsbn, isbn));
        return Collections.singletonMap("exists", count > 0);
    }

    @Override
    public PageResult<BookVO> queryBooksByPage(BookPageQuery query) {
        LambdaQueryWrapper<Book> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(query.getTitle()), Book::getTitle, query.getTitle())
                .like(StringUtils.hasText(query.getAuthor()), Book::getAuthor, query.getAuthor())
                .eq(StringUtils.hasText(query.getCategory()), Book::getCategory, query.getCategory())
                .orderByDesc(Book::getCreateTime);

        Page<Book> page = new Page<>(query.getPageNum(), query.getPageSize());
        this.page(page, wrapper);

        List<BookVO> voList = page.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult<>(voList, page.getTotal());
    }

    @Override
    public void deleteBookById(Long id) {
        if (!this.removeById(id)) {
            throw new ServiceException(ErrorCode.NOT_FOUND, "图书不存在或已被删除，删除失败");
        }
    }

    @Override
    public BookVO restoreBookById(Long id) {
        if (baseMapper.restoreById(id) <= 0) {
            throw new ServiceException(ErrorCode.NOT_FOUND, "图书不存在或未被删除，无法恢复");
        }
        Book book = baseMapper.selectById(id);
        return convertToVO(book);
    }

    private BookVO convertToVO(Book book) {
        BookVO vo = new BookVO();
        BeanUtils.copyProperties(book, vo);
        return vo;
    }
}